import {asyncRouterMap, constantRouterMap} from '@/config/router.config'
import {getUserMenus} from '@/api/menu'
import store from '@/store'
import {RouteView} from '@/layouts'

/**
 * 过滤账户是否拥有某一个权限，并将菜单从加载列表移除
 *
 * @param permission
 * @param route
 * @returns {boolean}
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  }
  return true
}

/**
 * 单账户多角色时，使用该方法可过滤角色不存在的菜单
 *
 * @param roles
 * @param route
 * @returns {*}
 */
// eslint-disable-next-line
function hasRole(roles, route) {
  if (route.meta && route.meta.roles) {
    return route.meta.roles.includes(roles.id)
  } else {
    return true
  }
}

function filterAsyncRouter(routerMap, roles) {
  const accessedRouters = routerMap.filter(route => {
    if (hasPermission(roles, route)) {
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children, roles)
      }
      return true
    }
    return false
  })
  return accessedRouters
}

/**
 * 递归组装路由表，返回符合用户角色权限的路由表（路由表后台配置时使用）
 * add by jeebase
 * @param resources
 */
function assembleAsyncRoutes(resources) {
  const accessedRouters = []
  resources.forEach(resource => {
    var route = {}
    if (resource.node.href === null) {
      route = {
        path: resource.nodeId + '_key',
        component: RouteView,
        name: 'menu_' + resource.nodeId,
        meta: {
          title: resource.node.menuName,
          icon: resource.node.menuIcon
        }
      }
    } else if (resource.children && resource.children.length) { // 包含子菜单的二级以下菜单
      route = {
        path: resource.node.href,
        component: RouteView,
        name: 'menu_' + resource.nodeId,
        meta: {
          title: resource.node.menuName,
          icon: resource.node.menuIcon
        }
      }
    } else { // 最后一层菜单
      route = {
        path: resource.node.href,
        component: resolve => require([`@/views${resource.node.href}/index`], resolve), // () => import(`@/views${item.node.href}/index`)
        name: 'menu_' + resource.nodeId,
        meta: {
          title: resource.node.menuName,
          icon: resource.node.menuIcon
        }
      }
    }

    if (resource.node.menuIcon === null) delete route.meta.icon
    if (resource.children && resource.children.length) {
      route.children = assembleAsyncRoutes(resource.children)
    }
    accessedRouters.push(route)
  })
  return accessedRouters
}

const permission = {
  state: {
    routers: constantRouterMap,
    addRouters: []
  },
  mutations: {
    SET_ROUTERS: (state, routers) => {
      state.addRouters = routers
      state.routers = constantRouterMap.concat(routers)
    }
  },
  actions: {
    GenerateRoutes({commit}, roles) {
      // eslint-disable-next-line no-undef
      return new Promise(resolve => {
        const accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
        commit('SET_ROUTERS', accessedRouters)
        resolve()
      })
    },
    GenerateResourcesRouters({commit}, roles) {
      return new Promise(resolve => {
        getUserMenus(store.getters.id).then(res => {
          let accessedRouters
          const resources = res.data
          if (resources && resources.length > 0) {
            const basicMenus = asyncRouterMap.find(item => item.path === '/').children
            asyncRouterMap.find(item => item.path === '/').children = basicMenus.concat(assembleAsyncRoutes(resources))
            accessedRouters = asyncRouterMap
          } else {
            accessedRouters = filterAsyncRouter(asyncRouterMap, [])
          }
          commit('SET_ROUTERS', accessedRouters)
          resolve(accessedRouters)
        })
      })
    }
  }
}

export default permission
